<template>
  <div class="editer">
    <ChapterManager :bookPath="bookPath" @onChapterClick="handleChapterClick"></ChapterManager>
    <div class="editer-main">
      <div class="editer-content">
        <div class="editer-toolbar">
          <el-dropdown trigger="click" @command="fontSizeCommand">
            <span class="el-dropdown-link font-size">
              {{ fontSize || "字号" }}<el-icon class="el-icon--right"><i-ep-CaretBottom /></el-icon>
            </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item v-for="(item, index) in fontSizeList" :key="index" :command="item">{{ item }}</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-dropdown trigger="click" @command="fontFamilyCommand">
            <span class="el-dropdown-link font-family">
              {{ fontFamily || "字体" }}<el-icon class="el-icon--right"><i-ep-CaretBottom /></el-icon>
            </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item v-for="(item, index) in fontFamilyList" :key="index" :command="item">{{ item }}</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-dropdown trigger="click" @command="lineHeightCommand">
            <span class="el-dropdown-link line-height">
              {{ lineHeihgt || "行高" }}<el-icon class="el-icon--right"><i-ep-CaretBottom /></el-icon>
            </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item v-for="(item, index) in lineHeightList" :key="index" :command="item">{{ item }}</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-tooltip effect="dark" content="加粗" placement="bottom" show-after="2000">
            <button :class="{ active: fontWeight === 'bold' }" class="icon-btn font-weight" @click="clickFontWeight">B</button>
          </el-tooltip>
          <el-tooltip effect="dark" content="倾斜" placement="bottom" show-after="2000">
            <button :class="{ active: fontStyle === 'italic' }" class="icon-btn font-style" @click="clickFontStyle">I</button>
          </el-tooltip>
          <el-tooltip effect="dark" content="一键排版" placement="bottom" show-after="2000">
            <button class="icon-btn layout" @click="clickLayout">
              <el-icon><i-ep-Tickets /></el-icon>
            </button>
          </el-tooltip>
          <el-tooltip effect="dark" content="一键复制" placement="bottom" show-after="2000">
            <button class="icon-btn copy" @click="clickCopy">
              <el-icon><i-ep-DocumentCopy /></el-icon>
            </button>
          </el-tooltip>
          <el-tooltip effect="dark" content="保存" placement="bottom" show-after="2000">
            <button class="icon-btn save" @click="clickSave(false)">
              <MzIcon name="icon-save" />
            </button>
          </el-tooltip>
          <el-tooltip effect="dark" content="搜索替换" placement="bottom" show-after="2000">
            <button class="icon-btn copy" @click="showSearchReplace = !showSearchReplace">
              <el-icon><i-ep-Search /></el-icon>
            </button>
          </el-tooltip>
          <SearchReplace v-model:visible="showSearchReplace" :resultCount="searchCount" @onInput="handleSearchInput" @onReplace="handleSearchReplace" />
        </div>
        <div ref="editerBody" v-html="editerHtml" :style="{ fontSize, fontFamily, lineHeight: lineHeihgt + 'em', fontWeight, fontStyle, textIndent }" class="editer-body" contenteditable="true"></div>
      </div>
      <div class="editer-statistical-column">
        <span class="book-word-count">全书字数：{{ bookWordCount }}字</span>
        <span class="chapter-word-count">章节字数：{{ chapterWordCount }}字</span>
        <span class="current-time">{{ currentTime }}</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * 文本编辑主窗口
 */
import { onBeforeUnmount, ref, onMounted, computed, watch, watchEffect } from "vue";
import { useRoute } from "vue-router";
import { dayjs, ElMessage } from "element-plus";
import "element-plus/es/components/message/style/css";
import { useClipboard, useMagicKeys } from "@vueuse/core";
import { useBookStore } from "@/store/modules/bookStore";

const route = useRoute();
const bookStore = useBookStore();

let intervalTime: any = null;
// 每隔300秒自动保存一次文本
const SAVE_INTERVAL = 300;

// 当前编辑书籍的路径
const bookPath = computed(() => {
  return route.query.path;
});

// 当前选中章节的本地路径
const currentChapterPath = ref("");
// 当前编辑文本对应的ref
const editerBody = ref();
// 从txt中获取的文本转成html现实
const editerHtml = ref("");

// 全书字数
const bookWordCount = ref(0);
// 章节字数
const chapterWordCount = ref(0);
// 当前日期时间
const currentTime = ref("");
// 字号列表
const fontSizeList = ["12px", "14px", "16px", "18px", "20px", "22px", "24px", "26px", "28px", "30px"];
// 字体列表
const fontFamilyList = ["黑体", "仿宋", "楷体", "华文仿宋", "华文行楷", "华文楷体", "华文隶书", "华文细黑"];
// 行高列表
const lineHeightList = ["1", "1.25", "1.5", "1.75", "2", "2.5", "3"];

// 选中字号
const fontSize = ref("");
// 选中字体
const fontFamily = ref("");
// 选中行高
const lineHeihgt = ref("");
// 字体加粗
const fontWeight = ref("normal");
// 字体倾斜
const fontStyle = ref("normal");
// 首行缩进
const textIndent = ref("");
// 是否展示搜索替换组件
const showSearchReplace = ref(false);

onMounted(() => {
  bookStore.setBookPath(route.query.path);

  let n = 0;
  currentTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
  intervalTime = setInterval(() => {
    n++;
    currentTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
    chapterWordCount.value = editerBody.value.textContent.length;
    // 每隔一段时间保存一次文章
    if (n % SAVE_INTERVAL === 0) {
      clickSave(true);
    }
    // TODO 每隔15秒记录一次内容，用于撤销和恢复
  }, 1000);
});

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  clearInterval(intervalTime);
});

// 字号列表选择确认
const fontSizeCommand = (command: string) => {
  fontSize.value = command;
};
// 字体列表选择确认
const fontFamilyCommand = (command: string) => {
  fontFamily.value = command;
};
// 行高列表选择确认
const lineHeightCommand = (command: string) => {
  lineHeihgt.value = command;
};
// 字体加粗点击
const clickFontWeight = () => {
  if (fontWeight.value === "normal") {
    fontWeight.value = "bold";
  } else {
    fontWeight.value = "normal";
  }
};
// 字体倾斜点击
const clickFontStyle = () => {
  if (fontStyle.value === "normal") {
    fontStyle.value = "italic";
  } else {
    fontStyle.value = "normal";
  }
};
// 点击一键排版
const clickLayout = () => {
  let tempFontSize = Number(fontSize.value.slice(0, 2)) || 16;
  textIndent.value = tempFontSize * 2 + "px";
};

const { copy, copied, isSupported } = useClipboard();
watch(copied, (e: boolean) => {
  if (e) {
    ElMessage({
      message: "已复制本章内容",
      type: "success"
    });
  }
});
// 点击一键复制
const clickCopy = () => {
  let innerText = editerBody.value.innerText;
  innerText = innerText.replace(/\n\n\n/g, "\n\n");
  if (isSupported.value) {
    copy(innerText);
  } else {
    ElMessage({
      message: "不支持复制",
      type: "warning"
    });
  }
};

// 获取当前选中的章节数据
const handleChapterClick = (e: any) => {
  currentChapterPath.value = e.path;
  window.electronAPI.readFile(e.path).then((res) => {
    let allParagraph: string[] | string = res.toString().split("\n");
    allParagraph = allParagraph.map((ele) => {
      if (ele) {
        return `<div>${ele}</div>`;
      } else {
        return "<br />";
      }
    });
    allParagraph = allParagraph.join("");
    editerHtml.value = allParagraph;
  });
};

// 搜索结果数量
const searchCount = ref(0);
// 搜索值输入变化时，实时查询匹配，并高亮显示匹配内容
const handleSearchInput = (e: any) => {
  let innerHTML = editerBody.value.innerHTML;
  // 先清空已有匹配项
  const regSpan1 = new RegExp('<span style="background-color:yellow;">', "g");
  const regSpan2 = new RegExp("</span>", "g");
  innerHTML = innerHTML.replace(regSpan1, "");
  innerHTML = innerHTML.replace(regSpan2, "");
  if (e) {
    const reg = new RegExp(e, "g");
    // 获取查询匹配数量
    const matchRes = innerHTML.match(reg);
    searchCount.value = matchRes ? matchRes.length : 0;
    // 对应匹配项高亮
    innerHTML = innerHTML.replace(reg, `<span style="background-color:yellow;">${e}</span>`);
  } else {
    searchCount.value = 0;
  }
  editerHtml.value = innerHTML;
};
// 替换搜索的文本内容
const handleSearchReplace = (sv: string, rv: string) => {
  let innerHTML = editerBody.value.innerHTML;
  const reg = new RegExp(`<span style="background-color:yellow;">${sv}</span>`, "g");
  innerHTML = innerHTML.replace(reg, rv);
  editerHtml.value = innerHTML;
};

// 点击保存，将内容保存成文本，并更新本地txt文件
const clickSave = (type?: boolean) => {
  let innerText = editerBody.value.innerText;
  innerText = innerText.replace(/\n\n\n/g, "\n\n");
  if (!currentChapterPath.value) {
    ElMessage({
      message: "章节有误，请重新点击确认章节",
      type: "warning"
    });
    return;
  }
  window.electronAPI.writeFile(currentChapterPath.value, innerText).then((res) => {
    if (res && !type) {
      ElMessage({
        message: "已保存",
        type: "success"
      });
    }
  });
};

// 监听键盘按键，组合键
const { Ctrl_F, Cmd_F } = useMagicKeys();
watch(Ctrl_F, (v) => {
  if (v && window.electronAPI.platform === "win32") {
    showSearchReplace.value = true;
  }
});
watch(Cmd_F, (v) => {
  if (v && window.electronAPI.platform === "darwin") {
    showSearchReplace.value = true;
  }
});
</script>

<style lang="scss" scoped>
.editer {
  height: 100vh;
  display: flex;
  overflow: hidden;
  &-main {
    flex: 1;
    position: relative;
  }
  &-content {
    height: calc(100vh - 27px);
    position: relative;
    display: flex;
    flex-direction: column;
  }
  &-statistical-column {
    font-size: 12px;
    height: 26px;
    line-height: 26px;
    border-top: 1px solid var(--el-border-color);
    position: absolute;
    bottom: 0px;
    left: 0px;
    right: 0px;
    padding: 0px 15px;
    background-color: var(--el-bg-color);
    .book-word-count {
      margin-right: 15px;
    }
    .current-time {
      float: right;
      font-variant-numeric: tabular-nums;
    }
  }
  &-toolbar {
    height: 40px;
    padding: 0px 15px;
    border-bottom: 1px solid var(--el-border-color);
    display: flex;
    align-items: center;
    color: var(--el-text-color-primary);
    position: relative;
    .el-dropdown-link {
      cursor: pointer;
      display: inline-block;
      display: flex;
      align-items: center;
      justify-content: space-between;
      background-color: var(--el-bg-color-page);
      padding: 5px;
      font-size: 12px;
      border-radius: 4px;
      margin-right: 15px;
      &.font-size {
        width: 60px;
      }
      &.font-family {
        width: 80px;
      }
      &.line-height {
        width: 60px;
      }
      &:hover {
        background-color: var(--el-color-primary-light-9);
        color: var(--el-color-primary);
      }
    }
    .icon-btn {
      width: 22px;
      height: 22px;
      margin-right: 15px;
      font-family: "Times New Roman", Times, serif;
      font-size: 18px;
      cursor: pointer;
      border: none;
      padding: 0px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: none;
      border-radius: 4px;
      &:hover {
        color: var(--el-color-primary);
      }
      &.active {
        background-color: var(--el-bg-color-page);
      }
      &.font-weight {
        font-weight: bold;
      }
      &.font-style {
        font-style: italic;
      }
    }
  }
  &-body {
    flex: 1;
    height: 100px;
    background-color: var(--el-fill-color-lighter);
    outline: none;
    padding: 15px;
    overflow: auto;
    font-size: 16px;
    line-height: 1.5em;
    span {
      background-color: yellow;
    }
  }
}
</style>
